package com.xiezc.springboot_dht.entityx;

import com.xiezc.springboot_dht.message.Message;
import com.xiezc.springboot_dht.message.MessageBuild;
import com.xiezc.springboot_dht.model.BeString;
import com.xiezc.springboot_dht.util.Const;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author wb-xzc291800
 * @date 2018/04/27 11:31
 */
@Data
@Slf4j
public class Bucket extends ConcurrentHashMap<BeString, Node> {

    /**
     * 桶的默认大小, 可以修改
     */
    private static final int KBucketSize = Const.KBucketSize;

    /**
     * 桶是否是满的标识
     */
    volatile boolean isFull;

    private int Bk;

    public Bucket(int bk) {
        this.Bk = bk;
    }

    /**
     * 根据key获得val
     *
     * @param id
     * @return
     */
    public Node getByKey(BeString id) {
        return super.get(id);
    }

    /**
     * 获得集合中过期的元素
     *
     * @return
     */
    public void refresh() {

        Iterator<Entry<BeString, Node>> iterator = entrySet().iterator();
        while (iterator.hasNext()) {
            Entry<BeString, Node> next = iterator.next();
            Node node = next.getValue();
            if (!node.isAlive()) {
                Message message = MessageBuild
                    .buildReqMsg()
                    .buildAId(Const.thisId)
                    .buildPing(node.getSocketAddress());
                log.error("放入缓存node:{},", node.getId());
                Node.putCahce(node);
                Const.sendCache.add(message);
                iterator.remove();
            }
        }
        isFull = size() >= KBucketSize;
    }

    /**
     * @param node
     * @return
     */
    public boolean put(Node node) {

        //如果没满
        if (isFull) {
            refresh();
        }
        if (isFull) {
            //TODO 还是满的, 放入缓存
            Node.putCahce(node);
            return false;
        }

        put(node.getId(), node);
        isFull = size() >= KBucketSize;
        return true;
    }

}
